package textconvert;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * HTML to text converter
 * 
 *
 */
public class HtmlTextConverter extends InputStream {
	private BufferedInputStream htmlStream;
	private IStyleCallback styleCallback = null;
	
	public HtmlTextConverter(InputStream htmlStream, IStyleCallback styleCallback ){
		this.htmlStream = new BufferedInputStream(htmlStream);	
		this.styleCallback = styleCallback;
	}

	public final int read() throws IOException{
		for(;;) {
			
			byte c = (byte)htmlStream.read();
			if(c != '<') 
				return c;
			
			//tag start : <
			
			ConstByteArray arr = htmlStream.byteBufferPeekLock(16);
			c = arr.byteAt(0);
			int arr_len = arr.length();
			//<a
			if((c==(byte)'a'||c==(byte)'A') && arr_len>2 && isWhiteSpaceOrEndTag(arr.byteAt(1)) ){
				htmlStream.byteBufferUnlock(1);  //skip 'a'
				arr = htmlStream.findBytePeekLock((byte)'>', 2048);
				if(arr==null)
					return -1;
				if(styleCallback!=null)
					styleCallback.startHref(getHref(arr.toString("UTF-8")));
				htmlStream.byteBufferUnlock(arr.length() + 1);  //also include '>';	
				return htmlStream.read();
			}		
			//</ a>
			if(c=='/'){  //</
				if(arr_len>3 && arr.byteAt(1)==(byte)'a' && arr.byteAt(2)==(byte)'>'){
					if(styleCallback!=null)
						styleCallback.endHref();
					htmlStream.byteBufferUnlock(3); 
					return htmlStream.read();
				}
				htmlStream.byteBufferUnlock(1);  //skip '/'
				arr = htmlStream.findBytePeekLock((byte)'>', 64);
				if(arr==null)
					return -1;
				String str = arr.toString("UTF-8").trim();
				htmlStream.byteBufferUnlock(arr.length() + 1);  //also include '>';	
				if(str.equalsIgnoreCase("a")){  //</ a >
					if(styleCallback!=null)
						styleCallback.endHref();
				}else if(str.equalsIgnoreCase("tr")){  //</ tr>
//					return '\t';
				}			
				continue;
			}
			//new line: <hr> <hr />,<br> <br />
			if( arr_len>1 && 
					(arr.byteAt(1)==(byte)'r'||arr.byteAt(1)==(byte)'R') && 
						(c==(byte)'h'||c==(byte)'H' || c==(byte)'b'||c==(byte)'B') )
			{
				htmlStream.byteBufferUnlock(2);  
				arr = htmlStream.findBytePeekLock((byte)'>', 64);
				if(arr==null)
					return -1;
				String str = arr.toString("UTF-8").trim();
				htmlStream.byteBufferUnlock(arr.length() + 1);  //also include '>';	
				if(str.length()==0 || str.equals("/"))
					return '\t';
				continue;
			}
			//skip: <script>, <link>
			else
			{
				htmlStream.byteBufferUnlock(0);  
				arr = htmlStream.findBytePeekLock((byte)'>', 1024);	
				if(arr==null || arr.length()<=0)
					return -1;
				htmlStream.byteBufferUnlock(arr.length() + 1);  //also include '>';	
				continue;
			}	
		
		} //~for
	}

	

	public final void close(){
		if(htmlStream!=null){
			htmlStream.close();
			htmlStream = null;
		}
	}
	/**
	 * 
	 * @param str  href="xxxxxx"
	 * @return
	 */
	private String getHref(String str){
		str = str.substring(str.indexOf("=") + 1);
		int p1 = str.indexOf('"');
		int p2 = str.lastIndexOf('"');
		return str.substring(++p1, p2);
	}
	
	
	
//	private static boolean isXmlWhiteSpace(byte c){
//		return c==' ' || c=='\t' || c=='\r' || c=='\n';
//	}
//	
//	private static int seekByte(byte[] str, int offset, int endoffset,byte c){
//		for(int i=offset;i<=endoffset; i++){
//			if(str[i]==c)
//				return i;
//		}
//		return -1;
//	}
//	
//	private static int seekXmlWhiteSpace(byte[] arr, int offset, int endoffset){
//		for(int i=offset;i<=endoffset; i++){
//			if( isXmlWhiteSpace(arr[i]) )
//				return i;
//		}
//		return -1;		
//	}
	
	private static boolean isWhiteSpaceOrEndTag(byte c){
		return c==' ' || c=='\t' || c=='\r' || c=='\n' || c=='>';		
	}

	
}
